<?php

/**
 * 工厂方法：通过工厂方法实现，但是不需要指定要创建的具体的子类。
 * 指定接口，将实例化委托给具体类或者基类实现并由派生类可选择的重写。
 * It provides a way to delegate the instantiation logic to child classes
 * Class FactoryMethod
 */

//面试问题接口
interface Interviewer
{
    public function askQuestions();
}

class Developer implements Interviewer
{
    public function askQuestions()
    {
        echo "Asking about design patters!";
    }
}

class CommunityExecutive implements Interviewer
{
    public function askQuestions()
    {
        echo "Asking about community building";
    }
}

// 人力资源经理抽象类。
// 借助于抽象类，实现工厂方法
abstract class HiringManager
{
    // 工厂方法
    abstract protected function makeInterviewer():Interviewer;


    public function takeInterview()
    {
        $interviewer = $this->makeInterviewer();
        $interviewer->askQuestions();
    }
}

// 开发经理，扩展抽象类
class DevelopmentManager extends HiringManager
{
    protected function makeInterviewer(): Interviewer
    {
        return new Developer();
    }
}

class MarketManager extends HiringManager
{
    protected function makeInterviewer(): Interviewer
    {
        return new CommunityExecutive();
    }
}

// usage
$devManager = new DevelopmentManager();
$devManager->takeInterview();

echo "\nCommunityInterview: \n";
$marketManager = new MarketManager();
$marketManager->takeInterview();